Skip to content

feat: add popup close policy and dock screen tracking - #1783

Open
wjyrich wants to merge 1 commit into
linuxdeepin:masterfrom
wjyrich:pr/folder-popup-foundation
Open

wjyrich wants to merge 1 commit into
linuxdeepin:masterfrom
wjyrich:pr/folder-popup-foundation

Conversation

@wjyrich

@wjyrich wjyrich commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor
  1. Add closeOnInactive property to PanelPopup to allow popups to stay open when the window becomes inactive
  2. Guard all internal auto-close paths (focus loss, grab timeout, ungrab, interaction end) behind closeOnInactive
  3. Track the panel's QWindow screen in DockPositioner and expose availableGeometry with change notifications
  4. Reconnect screen signals on screenChanged to follow panels moved across screens
  5. Fix popup parent fallback from undefined to null for cleaner QML binding semantics
  6. Add QML lifecycle smoke tests for PanelPopup covering open/close, shared window switching, and focus loss scenarios
  7. Wire qmltestrunner into CTest with offscreen platform for headless popup policy testing

Log: Added closeOnInactive option for panel popups and availableGeometry tracking in DockPositioner

Influence:

  1. Test popup open/close toggle behavior with repeated clicks
  2. Verify popups remain open when closeOnInactive is false and focus is lost
  3. Verify popups close automatically when closeOnInactive is true and focus is lost via activeChanged, grab timeout, or ungrab
  4. Test switching popups sharing the same popup window keeps the new owner open
  5. Verify stale close calls from previous popup owners do not close the new owner
  6. Test DockPositioner availableGeometry updates when moving panel across screens
  7. Verify availableGeometryChanged signal fires on screen change and available geometry change
  8. Run QML tests via ctest to validate popup lifecycle policies

feat: 添加弹窗关闭策略和任务栏屏幕跟踪

  1. 为 PanelPopup 添加 closeOnInactive 属性,允许弹窗在窗口失活时保持打开
  2. 将内部所有自动关闭路径(焦点丢失、抓取超时、取消抓取、交互结束)置于 closeOnInactive 控制之下
  3. 在 DockPositioner 中跟踪面板 QWindow 所在屏幕,并暴露带变更通知 的 availableGeometry
  4. 在 screenChanged 时重新连接屏幕信号,以跟随跨屏移动的面板
  5. 修复弹窗 parent 回退值从 undefined 改为 null,使 QML 绑定语义更清晰
  6. 新增 PanelPopup 的 QML 生命周期冒烟测试,覆盖打开关闭、共享窗口切换和 焦点丢失场景
  7. 将 qmltestrunner 接入 CTest,使用离屏平台进行无头弹窗策略测试

Log: 新增面板弹窗 closeOnInactive 选项和 DockPositioner 的
availableGeometry 跟踪

Influence:

  1. 测试重复点击时的弹窗打开关闭切换行为
  2. 验证 closeOnInactive 为 false 时焦点丢失后弹窗保持打开
  3. 验证 closeOnInactive 为 true 时通过 activeChanged、抓取超时或取消抓取 导致焦点丢失后弹窗自动关闭
  4. 测试共享同一弹窗窗口的弹窗切换时新所有者保持打开
  5. 验证旧弹窗所有者的过期关闭调用不会关闭新所有者
  6. 测试面板跨屏移动时 DockPositioner 的 availableGeometry 更新
  7. 验证屏幕切换和可用几何变化时触发 availableGeometryChanged 信号
  8. 通过 ctest 运行 QML 测试以验证弹窗生命周期策略

PMS: TASK-397247

Summary by Sourcery

Add configurable popup inactivity behavior and track the available geometry of the panel’s current screen.

New Features:

  • Add a configurable closeOnInactive policy for PanelPopup instances.
  • Expose screen-aware availableGeometry tracking through DockPositioner.

Bug Fixes:

  • Prevent stale popup owners from closing a newly active shared popup and use null for unavailable popup parents.

Enhancements:

  • Reconnect DockPositioner screen signals when panels move between screens.

CI:

  • Register headless QML lifecycle tests with CTest.

Tests:

  • Add QML smoke coverage for popup toggling, shared-window ownership, focus-loss policies, and screen geometry updates.

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: wjyrich

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai

sourcery-ai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

Adds a configurable PanelPopup inactivity-close policy, makes DockPositioner available geometry follow the panel’s current screen, and adds headless QML lifecycle tests registered through CTest.

Sequence diagram for PanelPopup inactivity close policy

sequenceDiagram
    participant PopupWindow
    participant PanelPopup
    participant QMLTest

    QMLTest->>PanelPopup: open()
    PanelPopup->>PopupWindow: currentItem = PanelPopup
    PopupWindow-->>PanelPopup: activeChanged
    alt closeOnInactive is true
        PanelPopup->>PanelPopup: close()
        PanelPopup->>PopupWindow: currentItem = null
    else closeOnInactive is false
        PanelPopup-->>QMLTest: remains open
    end

    QMLTest->>PanelPopup: closeOnInactive = false
    PopupWindow-->>PanelPopup: activeChanged
    PanelPopup-->>QMLTest: remains open
Loading

File-Level Changes

Change Details Files
Add configurable inactivity handling to panel popups while preserving ownership-safe close behavior.
  • Expose the closeOnInactive QML property, defaulting to automatic closure.
  • Gate focus-loss, grab timeout, ungrab, and interaction-end close paths on the policy.
  • Close an inactive popup when the policy is enabled after a policy change.
  • Use null rather than undefined for the popup content parent fallback.
  • Cover toggling, focus-loss variants, policy changes, shared-window switching, and stale-owner closes.
frame/qml/PanelPopup.qml
tests/frame/qml/tst_panelpopup.qml
Track the panel’s screen and expose screen-specific dock geometry to QML.
  • Add the availableGeometry property and change notification.
  • Initialize and update the tracked screen from the panel window’s screenChanged signal.
  • Reconnect available-geometry and destruction signals when the panel moves between screens.
  • Return an empty rectangle when no screen is available.
panels/dock/dockpositioner.cpp
panels/dock/dockpositioner.h
Integrate headless QML lifecycle coverage into the CTest test suite.
  • Discover qmltestrunner and register the frame QML suite with CTest.
  • Run tests using offscreen Qt, software rendering, and the frame/dock libraries preloaded.
  • Add automated popup lifecycle smoke tests for the new close policy and shared-window behavior.
tests/CMakeLists.txt
tests/frame/qml/tst_panelpopup.qml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

1. Add closeOnInactive property to PanelPopup to allow popups to stay
open when the window becomes inactive
2. Guard all internal auto-close paths (focus loss, grab timeout,
ungrab, interaction end) behind closeOnInactive
3. Track the panel's QWindow screen in DockPositioner and expose
availableGeometry with change notifications
4. Reconnect screen signals on screenChanged to follow panels moved
across screens
5. Fix popup parent fallback from undefined to null for cleaner QML
binding semantics
6. Add QML lifecycle smoke tests for PanelPopup covering open/close,
shared window switching, and focus loss scenarios
7. Wire qmltestrunner into CTest with offscreen platform for headless
popup policy testing

Log: Added closeOnInactive option for panel popups and availableGeometry
tracking in DockPositioner

Influence:
1. Test popup open/close toggle behavior with repeated clicks
2. Verify popups remain open when closeOnInactive is false and focus
is lost
3. Verify popups close automatically when closeOnInactive is true and
focus is lost via activeChanged, grab timeout, or ungrab
4. Test switching popups sharing the same popup window keeps the new
owner open
5. Verify stale close calls from previous popup owners do not close the
new owner
6. Test DockPositioner availableGeometry updates when moving panel
across screens
7. Verify availableGeometryChanged signal fires on screen change and
available geometry change
8. Run QML tests via ctest to validate popup lifecycle policies

feat: 添加弹窗关闭策略和任务栏屏幕跟踪

1. 为 PanelPopup 添加 closeOnInactive 属性,允许弹窗在窗口失活时保持打开
2. 将内部所有自动关闭路径(焦点丢失、抓取超时、取消抓取、交互结束)置于
closeOnInactive 控制之下
3. 在 DockPositioner 中跟踪面板 QWindow 所在屏幕,并暴露带变更通知
的 availableGeometry
4. 在 screenChanged 时重新连接屏幕信号,以跟随跨屏移动的面板
5. 修复弹窗 parent 回退值从 undefined 改为 null,使 QML 绑定语义更清晰
6. 新增 PanelPopup 的 QML 生命周期冒烟测试,覆盖打开关闭、共享窗口切换和
焦点丢失场景
7. 将 qmltestrunner 接入 CTest,使用离屏平台进行无头弹窗策略测试

Log: 新增面板弹窗 closeOnInactive 选项和 DockPositioner 的
availableGeometry 跟踪

Influence:
1. 测试重复点击时的弹窗打开关闭切换行为
2. 验证 closeOnInactive 为 false 时焦点丢失后弹窗保持打开
3. 验证 closeOnInactive 为 true 时通过 activeChanged、抓取超时或取消抓取
导致焦点丢失后弹窗自动关闭
4. 测试共享同一弹窗窗口的弹窗切换时新所有者保持打开
5. 验证旧弹窗所有者的过期关闭调用不会关闭新所有者
6. 测试面板跨屏移动时 DockPositioner 的 availableGeometry 更新
7. 验证屏幕切换和可用几何变化时触发 availableGeometryChanged 信号
8. 通过 ctest 运行 QML 测试以验证弹窗生命周期策略

PMS: TASK-397247
@wjyrich
wjyrich force-pushed the pr/folder-popup-foundation branch from affff9b to 91315e1 Compare October 27, 2026 12:09
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 90 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 本次提交为 dde-shell 添加了弹窗关闭策略(closeOnInactive 属性)和 Dock 屏幕跟踪功能(availableGeometry), 代码整体结构清晰,测试覆盖充分,无安全漏洞。主要问题在于 dockpositioner.cpp 构造函数中未处理窗口未就绪的边界情况, 可能导致屏幕跟踪功能永久失效,建议增加延迟连接机制。

🔍 详细分析

1. 语法逻辑 ❌

评价: 存在逻辑缺陷 ❌ 不通过

潜在问题:
✅ 未发现明显问题

建议: ['建议在构造函数中使用 lambda 配合 rootObjectChanged 信号实现延迟连接, 当窗口未就绪时在 rootObjectChanged 触发后重试连接,确保屏幕跟踪在任何时候都能正常初始化。']


2. 代码质量 ✅

评价: 代码结构清晰,注释完整 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: ['建议为 setScreen() 和 availableGeometry() 方法添加简短的函数注释, 说明方法的目的和调用时机。']


3. 代码性能 ✅

评价: 性能良好,资源使用合理 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: []


4. 代码安全 🔒

评价: 存在0个安全漏洞 ✅ 通过

🔐 发现 0 个安全漏洞

安全漏洞详情:
✅ 未发现安全漏洞

建议: []


💡 改进建议代码示例

// dockpositioner.cpp 构造函数中改进屏幕跟踪初始化: // 使用 lambda 配合 rootObjectChanged 信号,确保窗口未就绪时延迟连接
DockPositioner::DockPositioner(DPanel *panel, QObject *parent)
    : QObject(parent), m_panel(panel)
{
    // ... 其他初始化代码 ...

    Q_ASSERT(m_panel);

    // 使用 lambda 封装屏幕跟踪初始化逻辑
    auto setupScreenTracking = [this]() {
        if (auto window = m_panel->window()) {
            connect(window, &QWindow::screenChanged, this, &DockPositioner::setScreen);
            setScreen(window->screen());
        }
    };
    setupScreenTracking();
    // 当窗口尚未就绪时,通过 rootObjectChanged 信号延迟重试
    connect(m_panel, &DPanel::rootObjectChanged, this, setupScreenTracking);

    connect(m_panel, SIGNAL(positionChanged(Position)), this, SLOT(update()));
    connect(m_panel, SIGNAL(geometryChanged(QRect)), this, SLOT(update()));
    // ...
}

本报告由 AI 代码审查工具自动生成

@deepin-bot

deepin-bot Bot commented Oct 28, 2026

Copy link
Copy Markdown

TAG Bot

New tag: 2.0.61
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #1786

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants